﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntitiesLayer;
using System.Transactions;
using System.Data.SqlClient;
using System.Data;

namespace DAL.Repositories
{
   internal class PlanetaRepository: IRepository<Planeta>
    {
        private IList<IEntity> insertedList;
        private IList<IEntity> updatedList;
        private IList<IEntity> deletedList;

        internal PlanetaRepository()
        {

            insertedList = new List<IEntity>();
            updatedList = new List<IEntity>();
            deletedList = new List<IEntity>();
        }

        public void Insert(Planeta entity)
        {
            insertedList.Add(entity);
        }

        public void Delete(Planeta entity)
        {
            deletedList.Add(entity);
        }

        public void Update(Planeta entity)
        {
            updatedList.Add(entity);
        }

        public IEnumerable<Planeta> GetAll()
        {
            SqlCommand cmd = new SqlCommand();
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "pa_listar_planetas");

            foreach (DataRow dr in ds.Tables[0].Rows)
              yield return  crearPlaneta(dr, Convert.ToInt32(dr["IDPLANETA"]));
            
        }

        public Planeta GetById(int id)
        {
            Planeta objSatelite = null;
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@pidpla", id));
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "pa_consultar_planeta_porID");

            foreach (DataRow dr in ds.Tables[0].Rows)
                objSatelite = crearPlaneta(dr, id);


            return objSatelite;

        }

        public void Save()
        {
            using (TransactionScope scope = new TransactionScope())
            {

                try
                {

                    foreach (Planeta p in insertedList)
                        InsertSatelite(p);

                    foreach (Planeta p in updatedList)
                        UpdateSatelite(p);

                    foreach (Planeta p in deletedList)
                        DeleteSatelite(p);


                    scope.Complete();
                }
                catch (TransactionAbortedException ex)
                {
                    Console.WriteLine(ex.Message);
                    throw ex;
                }
                catch (ApplicationException ex)
                {
                    Console.WriteLine(ex.Message);
                    throw ex;
                }
                finally
                {
                    Clear();
                }

            }
        }

        public void Clear()
        {
            insertedList.Clear();
            updatedList.Clear();
            deletedList.Clear();
        }
        #region Utilities
        private void InsertSatelite(Planeta objPlaneta)
        {

            try
            {
                //falta la duracionano 
                SqlCommand cmd = new SqlCommand();
                cmd.Parameters.Add(new SqlParameter("@nombre", objPlaneta.Nombre));
                cmd.Parameters.Add(new SqlParameter("@masa", objPlaneta.Masa));
                cmd.Parameters.Add(new SqlParameter("@temp", objPlaneta.TemperaturaMedia));
                cmd.Parameters.Add(new SqlParameter("@duracion", objPlaneta.Duracion.Ticks));
                cmd.Parameters.Add(new SqlParameter("@distancia", objPlaneta.DistanciaMediaSol));
                cmd.Parameters.Add(new SqlParameter("@duracionano", objPlaneta.DuracionAno.Ticks));

                DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "pa_RegistrarPlaneta");
            }
            catch (SqlException ex)
            {
                Console.WriteLine(ex.Message);
                throw ex;
            }

        }

        private void UpdateSatelite(Planeta objSatelite)
        {
            throw new NotImplementedException();

        }

        private void DeleteSatelite(Planeta objSatelite)
        {
            throw new NotImplementedException();

        }


        internal static IList<Satelite> consultarSatelitesDePlaneta(int idPlaneta)
        {

            IList<Satelite> listaSatelite = new List<Satelite>();
            SateliteRepository repoS=(SateliteRepository)(UnitOfWork.SateliteRepository);
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(new SqlParameter("@pidpla", idPlaneta));
            DataSet ds = DBAccess.ExecuteSPWithDS(ref cmd, "pa_consultar_satelites_del_planeta");


                foreach (DataRow drSatelites in ds.Tables[0].Rows)
                {
                    int id= Convert.ToInt32(drSatelites["IDSATELITE"]);
                    Satelite satelite = SateliteRepository.crearSatelite(drSatelites,id);
                    listaSatelite.Add(satelite);
                }
            

            return listaSatelite.Count < 1 ? null : listaSatelite;
        }

        internal static Planeta crearPlaneta(DataRow dr, int id)
        {
            
            Planeta objSatelite = new Planeta(

                    id: id,
                    nombre: dr["NOMBRE"].ToString(),
                    masa: Convert.ToDecimal(dr["MASA"]),
                    duracion: new TimeSpan(Convert.ToInt64(dr["DURACIONDIA"])),
                    temperaturaMedia: Convert.ToDecimal(dr["TEMPMEDIA"]),
                    distanciaMedia: Convert.ToDecimal(dr["DISTANCIASOL"]),
                    cantidadSatelites: Convert.ToInt32(dr["CANTSATELITES"]),
                    duracionAno: new TimeSpan(Convert.ToInt64(dr["DURACIONANO"])),
                    sateliteloader: new Lazy<IList<Satelite>>(()=>{
                        return consultarSatelitesDePlaneta(id);
                    }),
                    missionDelegate: new Lazy<IList<Mission>>(()=>{
                        return MissionRepository.consultarMissionesCuerpoCeleste(id);
                    })


                );

            return objSatelite;
        }

        #endregion Uttilities

    }
}
